﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using KindleComic.Core;

namespace KindleComic
{
    public partial class FrmComicDetails : Form
    {
        public FrmComicDetails()
        {
            InitializeComponent();
        }
        private ComicSource ComicSource { get; set; }
        public FrmComicDetails(string comicName, string comicAuthor, string comicUrl, string comicCover, ComicSource source)
        {
            InitializeComponent();
            this.Text = comicName;
            var comic = new ucComic();
            comic.ComicName = comicName;
            comic.ComicCover = comicCover;
            comic.ComicAuthor = comicAuthor;
            comic.ComicUrl = comicUrl;
            comic.ComicSource = source.ComicSourceName;
            comic.Margin = new Padding(10, 10, 0, 0);
            this.splitContainer1.Panel1.Controls.Add(comic);
            this.splitContainer1.SplitterDistance = comic.Height;
            this.splitContainer1.FixedPanel = FixedPanel.Panel1;
            this.splitContainer1.IsSplitterFixed = true;
            ComicSource = source;
            LoadChaper(comicUrl);
        }
        private List<ComicChapter> comicChapters;
        private Dictionary<string, bool> chapterImgLoadState = new Dictionary<string, bool>();
        public void LoadChaper(string url)
        {
            comicChapters = ComicSource.GetComicChapterAsync(url).Result;
            int i = 0;
            foreach (var item in comicChapters)
            {
                var comicName = this.Text;
                var chapterName = item.ChapterName;
                var chapterUrl = item.ChapterUrl;
                Button btn = new Button();
                btn.Text = chapterName;
                btn.Tag = chapterUrl;
                btn.Click += ComicChapter_Click;
                if (XMLOpteration.IsExistsNode(root =>
                    root.Elements("comicInfo")
                    .Where(x => x.Element("name").Value == comicName)
                    .Elements("chapterList")
                    .Elements("chapter")
                    .Any(x =>
                        x.Element("name").Value == chapterName
                        &&
                        x.Element("url").Value == chapterUrl
                        )
                    )
                    )
                {
                    btn.BackColor = Color.FromArgb(78, 110, 242);
                    btn.FlatStyle = FlatStyle.Flat;
                    btn.FlatAppearance.BorderColor = Color.FromArgb(78, 110, 242);
                    btn.ForeColor = Color.White;
                }
                this.flowLayoutPanel1.Controls.Add(btn);
                chapterImgLoadState[item.ChapterName + item.ChapterUrl] = false;
                //this.flowLayoutPanel1.Controls.SetChildIndex(btn, i);
                i++;
            }
            Task.Run(async () =>
            {
                foreach (var item in comicChapters)
                {
                    item.Images = await ComicSource.GetComicImagesAsync(item.ChapterUrl).ConfigureAwait(false);
                    chapterImgLoadState[item.ChapterName + item.ChapterUrl] = true;
                }
            });
        }

        private void ComicChapter_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                var btn = (Button)sender;
                DownloadComic(btn);
            });
        }

        private void DownloadComic(Button btn)
        {
            //已下载颜色变成蓝色，未下载颜色默认
            if (btn.BackColor != Color.FromArgb(78, 110, 242))
            {
                btn.BackColor = Color.FromArgb(78, 110, 242);
                btn.FlatStyle = FlatStyle.Flat;
                btn.FlatAppearance.BorderColor = Color.FromArgb(78, 110, 242);
                btn.ForeColor = Color.White;
                var chapterName = btn.Text;
                var url = btn.Tag?.ToString();
                while (!chapterImgLoadState[chapterName + url])
                {
                    Thread.Sleep(1000);
                }
                var chapter = comicChapters.Where(x => x.ChapterName == chapterName && x.ChapterUrl == url).FirstOrDefault();

                var ucComic = (ucComic)this.splitContainer1.Panel1.Controls[0];

                //记录信息到xml
                RecordComicDownloadInfo(ucComic, chapter);

                var basePath = ConfigurationManager.AppSettings["filePath"].ToString();
                var comicDirectory = Path.Combine(basePath, ucComic.ComicName);
                if (!Directory.Exists(comicDirectory))
                {
                    Directory.CreateDirectory(comicDirectory);
                }

                //开始下载 同时最多下载3个
                Parallel.ForEach(chapter.Images, new ParallelOptions()
                {
                    MaxDegreeOfParallelism = 3
                }, img =>
                 {
                     ComicSource.DownloadAsync(img.Value, Path.Combine(comicDirectory, chapterName, img.Key.ToString().PadLeft(4, '0') + ".jpg")).ContinueWith(x =>
                     {

                     }).ConfigureAwait(false);
                 });
            }
        }

        private void RecordComicDownloadInfo(ucComic ucComic, ComicChapter chapter)
        {
            lock (obj)
            {
                var author = ucComic.ComicAuthor;
                var comicUrl = ucComic.ComicUrl;
                var cover = ucComic.ComicCover;

                //将图片信息生成xml记录
                XElement imgListElement = new XElement("imgList", new XAttribute("complete", false));
                foreach (var item in chapter.Images)
                {
                    imgListElement.Add(new XElement("img",
                                                    new XAttribute("downloaded", false),
                                                    new XAttribute("sort", item.Key),
                                                    new XAttribute("src", item.Value)
                                    ));
                }
                if (!XMLOpteration.IsExistsNode(root =>
                        root.Elements("comicInfo")
                        .Any(x => x.Element("name").Value == this.Text)
                        )
                    )
                {
                    XMLOpteration.AddElement(new XElement("comicInfo",
                                                new XElement("name", this.Text),
                                                new XElement("author", author),
                                                new XElement("cover", cover),
                                                new XElement("url", comicUrl),
                                                new XElement("chapterList",
                                                    new XAttribute("complete", false),
                                                    new XElement("chapter",
                                                        new XElement("name", chapter.ChapterName),
                                                        new XElement("url", chapter.ChapterUrl),
                                                        imgListElement
                                                    )
                                                )
                                        ));
                }
                else
                {
                    XMLOpteration.AppendElement(root => root.Elements("comicInfo")
                .Where(x => x.Element("name").Value == this.Text).FirstOrDefault()
                .Element("chapterList"), new XElement("chapter",
                                                        new XElement("name", chapter.ChapterName),
                                                        new XElement("url", chapter.ChapterUrl),
                                                        imgListElement
                                                    ));
                }

            }
        }

        private readonly object obj = new object();
        private void btnReOrder_Click(object sender, EventArgs e)
        {
            var ChapterCount = this.flowLayoutPanel1.Controls.Count;
            foreach (Control btn in this.flowLayoutPanel1.Controls)
            {
                //var currentIndex = this.flowLayoutPanel1.Controls.GetChildIndex(btn);
                //var newIndex = currentIndex+ChapterCount;
                this.flowLayoutPanel1.Controls.SetChildIndex(btn, ChapterCount);
            }
        }

        private void btnDownloadAll_Click(object sender, EventArgs e)
        {
            foreach (Control control in this.flowLayoutPanel1.Controls)
            {
                var btn = (Button)control;
                btn.BackColor = Color.FromArgb(78, 110, 242);
            }

            Task.Run(() =>
            {
                Parallel.For(1, this.flowLayoutPanel1.Controls.Count, new ParallelOptions()
                {
                    MaxDegreeOfParallelism = 3
                }, i =>
                {
                    var btn = (Button)this.flowLayoutPanel1.Controls[i-1];
                    DownloadComic(btn);
                });
            });

            //var ChapterCount = this.flowLayoutPanel1.Controls.Count;
            //foreach (Control control in this.flowLayoutPanel1.Controls)
            //{
            //    var btn = (Button)control;
            //    DownloadComic(btn);
            //}
        }

        private void FrmComicDetails_Load(object sender, EventArgs e)
        {

        }
    }
}
